package com.inspur.security.cbb3.kms.keymanager.keyorders.controller;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inspur.security.cbb3.kms.annotation.SysLog;
import com.inspur.security.cbb3.kms.config.rabbitmq.RabbitConstant;
import com.inspur.security.cbb3.kms.enums.BusinessType;
import com.inspur.security.cbb3.kms.enums.SystemCode;
import com.inspur.security.cbb3.kms.keymanager.keyorders.po.KeyOrdersBean;
import com.inspur.security.cbb3.kms.keymanager.keyorders.service.KeyOrdersService;
import com.inspur.security.cbb3.kms.keymanager.keyorders.vo.KeyOrdersAddVO;
import com.inspur.security.cbb3.kms.rabbitmq.sender.SignWebSender;
import com.inspur.security.cbb3.kms.utils.PageRequestDate;
import com.inspur.security.cbb3.kms.utils.ResultUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import javassist.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.ValidationException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 密钥订单控制类
 *
 * @author lijunchang
 */
@RestController
@RequestMapping("/v1/keyorders")
@ApiModel(value = "密钥订单业务", description = "密钥订单业务")
@Slf4j
public class KeyOrdersController {

    @Autowired
    private KeyOrdersService keyOrdersService;

    @Value("${signweb.need.rabbitmq}")
    private boolean needRabbitMq = false;
    /**
     * rabbitmq
     */
    @Autowired
    private SignWebSender signWebSender;

    @PostMapping
    @ApiOperation(value = "密钥订单新增", notes = "密钥订单新增", httpMethod = "POST")
    @SysLog(title = "密钥订单新增", businessType = BusinessType.INSERT, isSaveRequestData = true)
    public ResponseEntity generateKeyOrder(@ApiParam(value = "传入新增密钥订单对象", required = true) @Valid KeyOrdersAddVO keyOrdersAddVO) {
        KeyOrdersBean bean = keyOrdersService.generateKeyOrder(keyOrdersAddVO);
        Map<String, String> returnMap = new HashMap<>(1);
        returnMap.put("keyorderRef", "/v1/keyorders/" + bean.getUuid());

        new Runnable() {
            /**
             * When an object implementing interface <code>Runnable</code> is used
             * to create a thread, starting the thread causes the object's
             * <code>run</code> method to be called in that separately executing
             * thread.
             * <p>
             * The general contract of the method <code>run</code> is that it may
             * take any action whatsoever.
             *
             * @see Thread#run()
             */
            @Override
            public void run() {
                //2.rabbitmq调用密钥生成方法||直接进行订单生成
                if (needRabbitMq) {
                    log.info("do mq,uuid:{}",bean.getUuid());
                    Map<String, String> message = new HashMap<>(2);
                    message.put("method", RabbitConstant.METHOD_KEYORDER_ADD);
                    message.put("uuid", bean.getUuid());
                    signWebSender.send(message);
                } else {
                    //直接进行生成
                    keyOrdersService.mqGenerateKeyOrder(bean.getUuid());
                }
            }
        }.run();

        return ResultUtil.objReturn(returnMap, HttpStatus.ACCEPTED);
    }


    @DeleteMapping("/{uuid}")
    @ApiOperation(value = "删除密钥订单", notes = "可以删除一条密钥订单信息", httpMethod = "DELETE")
    @SysLog(title = "删除密钥订单", businessType = BusinessType.DELETE)
    public ResponseEntity deleteKeyOrder(@PathVariable("uuid") String uuid) throws MissingServletRequestParameterException, NotFoundException {
        keyOrdersService.deleteKeyOrder(uuid);
        return ResultUtil.noDataReturn(SystemCode.SUCCESS, HttpStatus.NO_CONTENT);
    }

    @GetMapping
    @ApiOperation(value = "密钥订单列表查询", notes = "密钥订单列表查询", httpMethod = "GET")
    public ResponseEntity searchKeyOrders(@ApiParam(value = "传入分页条件") PageRequestDate pageRequestDate,
                                          @ApiParam(value = "传入查询条件") KeyOrdersBean searchParams) {
        Page<KeyOrdersBean> page = keyOrdersService.searchKeyOrders(pageRequestDate, searchParams);
        Map<String, Object> returnMap = new HashMap<>(2);
        returnMap.put("total", page.getTotalElements());
        if (page.getTotalElements() < 1) {
            returnMap.put("keyorders", null);
            return ResultUtil.objReturn(returnMap, HttpStatus.OK);
        }
        List<KeyOrdersBean> list = page.getContent();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        for (KeyOrdersBean bean : list) {
            assembleKeyOrdersBean(bean);
        }
        returnMap.put("keyorders", list);
        return ResultUtil.objReturn(returnMap, HttpStatus.OK);
    }

    @GetMapping("/{uuid}")
    @ApiOperation(value = "密钥订单信息查询", notes = "密钥订单信息查询,请将{uuid}替换成密钥订单主键", httpMethod = "GET")
    public ResponseEntity searchKeyOrder(@PathVariable("uuid") String uuid) throws MissingServletRequestParameterException, NotFoundException {
        KeyOrdersBean bean = keyOrdersService.searchKeyOrder(uuid);
        assembleKeyOrdersBean(bean);
        return ResultUtil.objReturn(bean, HttpStatus.OK);
    }

    /**
     * 进行返回信息组装
     *
     * @param bean 数据库对象
     */
    private void assembleKeyOrdersBean(KeyOrdersBean bean) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        KeyOrdersAddVO keyOrdersAddVO;
        try {
            keyOrdersAddVO = objectMapper.readValue(bean.getMeta(), KeyOrdersAddVO.class);
            keyOrdersAddVO.setPassword(null);
            keyOrdersAddVO.setKekId(null);
            bean.setMeta(objectMapper.writeValueAsString(keyOrdersAddVO));
        } catch (IOException e) {
            log.error("密钥订单信息查询转换数据错误");
            throw new ValidationException("密钥订单信息查询转换数据错误");
        }
        if (StringUtils.isNotBlank(bean.getSecretId())) {
            bean.setSecretRef("/v1/secrets/" + bean.getSecretId());
        }
        if (StringUtils.isNotBlank(bean.getContainerId())) {
            bean.setContainersRef("/v1/containers/" + bean.getContainerId());
        }
    }
}
